package com.qf.bbapi.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.bbapi.config.RedisKeyConfig;
import com.qf.bbapi.dao.UserDao;
import com.qf.bbapi.dao.UserLogDao;
import com.qf.bbapi.dto.*;
import com.qf.bbapi.entity.User;
import com.qf.bbapi.entity.UserLog;
import com.qf.bbapi.service.intf.UserService;
import com.qf.bbapi.type.UserLogType;
import com.qf.bbapi.util.JedisUtil;
import com.qf.bbapi.util.StringUtil;
import com.qf.bbapi.vo.R;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao userDao;
    @Resource
    private UserLogDao userLogDao;

    /*
    * 检测手机号*/
    @Override
    public R checkPhone(String phone) {
        //参数校验
        if(StringUtil.isNotEmpty(phone)){
            //再次参数校验
            if(StringUtil.isPhone(phone)){
                //从数据库中查询手机号
                QueryWrapper<User> wrapper = new QueryWrapper<>();
                wrapper.eq("phone",phone);
                User user = userDao.selectOne(wrapper);
                if(user==null){
                    return R.fail("请先去注册该手机号");
                }else{
                    return R.ok(user);
                }
            }else{
                return R.fail("输入手机号格式错误");
            }
        }
        return R.fail("输入手机号为空");
    }

    /*
    * 使用密码登录*/
    @Override
    public R loginPassword(UserPasswordLoginDto dto) {
        //参数校验
        if(dto!=null){
            //再次参数校验
            if(StringUtil.isNotEmpty(dto.getPassword(),dto.getPhone())){
                //从数据库中查询
                QueryWrapper<User> wrapper = new QueryWrapper<>();
                wrapper.eq("phone",dto.getPhone());
                wrapper.or().eq("name",dto.getPhone());
                User user = userDao.selectOne(wrapper);
                if(user!=null){
                    if(user.getPassword().equals(dto.getPassword())){
                        //判断该账号是否已经被登录过
                        if(JedisUtil.checkKey(RedisKeyConfig.USER_ID+user.getId())){
                            return R.fail("该账号已在别处登录！");
                        }else{
                            //将该账号的信息存入到redis中，有效期为30分钟
                            JedisUtil.addString(RedisKeyConfig.USER_ID+user.getId(), JSON.toJSONString(user),RedisKeyConfig.LOGIN_TIME);
                            //记录日志
                            userLogDao.insert(new UserLog(user.getId(), UserLogType.登录.getValue(),"完成了账号密码登录",dto.getCity(), dto.getMobile()));
                            return R.ok(user.getId());
                        }
                    }else{
                        return R.fail("手机号/用户名或密码错误！");
                    }
                }else{
                    return R.fail();
                }
            }else{
                return R.fail("手机号/用户名或密码为空！");
            }
        }
        return R.fail();
    }

    /*
    * 手机号验证码登录*/
    @Override
    public R loginCode(UserCodeLoginDto dto) {
        //参数校验
        if(dto!=null){
            if(StringUtil.isNotEmpty(dto.getPhone(),dto.getCode())){
                //检测手机号是否可用
                QueryWrapper<User> wrapper = new QueryWrapper<>();
                wrapper.eq("phone",dto.getPhone());
                User user = userDao.selectOne(wrapper);
                if(user!=null){
                    //验证验证码
                    if(dto.getCode().equals(JedisUtil.getString(RedisKeyConfig.SMS_CODE_LOGIN+dto.getPhone()))){
                        //判断是否只有一个用户登录该账号
                        if(JedisUtil.checkKey(RedisKeyConfig.USER_ID+user.getId())){
                            return R.fail("用户已在别处登录");
                        }else{
                            //添加用户日志表
                            userLogDao.insert(new UserLog(user.getId(), UserLogType.登录.getValue(),"完成了账号密码登录",dto.getCity(), dto.getMobile()));
                            return R.ok(user.getId());
                        }
                    }else{
                        return R.fail("验证码错误");
                    }
                }
            }
        }
        return R.fail();
    }

    /*
    * 找回密码*/
    @Override
    @Transactional//开启事务
    public R findPassword(UserFindDto dto) {
        //参数校验
        if(dto!=null){
            if(StringUtil.isNotEmpty(dto.getPassword(),dto.getCode(),dto.getPhone())){
                //查询手机号是否可用
                QueryWrapper<User> wrapper = new QueryWrapper<>();
                wrapper.eq("phone",dto.getPhone());
                User user = userDao.selectOne(wrapper);
                if(user!=null){
                    //验证验证码
                    if(dto.getCode().equals(JedisUtil.getString(RedisKeyConfig.SMS_CODE_LOGIN+dto.getPhone()))){
                        //修改用户表 修改密码
                        int i = userDao.updatePass(dto.getPhone(), dto.getPassword());
                        if(i>0){
                            //修改成功 记录日志
                            userLogDao.insert(new UserLog(user.getId(), UserLogType.密码找回.getValue(), "进行了密码找回，重置成功！", dto.getCity(), dto.getMobile()));
                            //判断是否只有一个用户登录该账号
                            if(JedisUtil.checkKey(RedisKeyConfig.USER_ID+user.getId())){
                                //如果已经登录，则将账号下线
                                JedisUtil.delKeys(RedisKeyConfig.USER_ID+user.getId());
                            }
                            return R.ok();
                        }else{
                            return R.fail("修改密码发生错误！");
                        }
                    }else{
                        return R.fail("验证码错误");
                    }
                }
            }
        }
        return R.fail();
    }

    @Override
    public R loginOut(int token) {
        if(token>0){
            if(JedisUtil.checkKey(RedisKeyConfig.USER_ID+token)){
                JedisUtil.delKeys(RedisKeyConfig.USER_ID+token);
                return R.ok();
            }
        }
        return R.fail("账号异常");
    }

    @Override
    @Transactional//开启事务
    public R regist(UserAddDto dto) {
        if(dto!=null){
            if(StringUtil.isNotEmpty(dto.getName(),dto.getPassword(),dto.getPhone(),dto.getCode())){
                //判断用户名和手机号是否被注册过
                QueryWrapper<User> wrapper = new QueryWrapper<>();
                wrapper.eq("phone",dto.getPhone());
                wrapper.or().eq("name",dto.getName());
                User user1 = userDao.selectOne(wrapper);
                if(user1==null){
                    //判断验证码是否正确
                    if(dto.getCode().equals(JedisUtil.getString(RedisKeyConfig.SMS_CODE_ADD+dto.getPhone()))){
                        //将用户添加到用户表
                        if(userDao.insert(new User(dto.getName(),dto.getPhone(),dto.getPassword()))>0){
                            QueryWrapper<User> wrapper1 = new QueryWrapper<>();
                            wrapper1.eq("phone",dto.getPhone());
                            User user = userDao.selectOne(wrapper1);
                            //添加用户日志表
                            userLogDao.insert(new UserLog(user.getId(),UserLogType.注册.getValue(), "用户成功注册",dto.getCity(),dto.getMobile()));
                            return R.ok();
                        }else{
                           return R.fail("添加用户失败！");
                        }
                    }else{
                        return R.fail("验证码错误！");
                    }
                }else{
                    return R.fail("用户名或者手机号已被注册过！");
                }
            }
        }
        return R.fail();
    }

    @Override
    public R updateData(UserDataDto dto, int token) {
        System.out.println(dto);
        if(dto != null && token > 0) {
            if (StringUtil.isPhone(dto.getPhone())) {
                User user = userDao.selectOne(new QueryWrapper<User>().eq("id", token));
                if (user != null) {
                    if (userDao.updateData(dto.getPhone(),dto.getSex(),dto.getEmail(),dto.getNickname(), token) > 0) {
                        return R.ok("修改成功");
                    }
                }
            }
        }
        return R.fail("修改失败");
    }

    @Override
    public R selectOne(int token) {
        if(token>0){
            QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("id", token);
            User user = userDao.selectOne(wrapper);
            if(user != null){
                return R.ok(user);
            }
        }
        return R.fail();
    }

}
